#!/bin/sh

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (C) 2013 - 2015 Open Microscopy Environment
#       Massachusetts Institute of Technology,
#       National Institutes of Health,
#       University of Dundee,
#       University of Wisconsin at Madison
#
# This work is licensed under the
#       Creative Commons Attribution 3.0 Unported License.
# To view a copy of this license, visit
#       http://creativecommons.org/licenses/by/3.0/
# or send a letter to
#       Creative Commons, 444 Castro Street, Suite 900,
#       Mountain View, California, 94041, USA.
# For attribution instructions, visit
#       http://www.openmicroscopy.org/info/attribution
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

set -e

XARGSOPTS=
xargs -r </dev/null 2>/dev/null >/dev/null && XARGSOPTS="-r"

# Parse date from a YYYY-MM string
parsedate() {
    if date -j 2>/dev/null >/dev/null; then
        echo $(date -jnu -f "%Y-%m" "$1" '+%B %Y')
    else
        echo $(date -d "${1}-01" '+%B %Y')
    fi
}

curdate() {
    date '+%B %Y'
}

# Get the most recent version of a schema
# $1=schema name
mostrecentversion() {
    echo "$(basename $(dirname $(find released-schema -name "$1" | grep -v $devmarker | sort | tail -n1)))"
}

# Check if the a schema is the most recent version (return true) or legacy (return false)
# $1=schema name
# $2=release to check if current
ismostrecent() {
    if [ "$2" != "$(mostrecentversion "$1")" ]; then
        return 1
    fi

    return 0
}

# Check if a schema is current (not necessarily the latest version).
# $1=schema name
iscurrent() {
    if [ "${1%.xsd}" = "AnalysisChain" ] || \
        [ "${1%.xsd}" = "AnalysisModule" ] || \
        [ "${1%.xsd}" = "CA" ] || \
        [ "${1%.xsd}" = "CLI" ] || \
        [ "${1%.xsd}" = "DataHistory" ] || \
        [ "${1%.xsd}" = "MLI" ] || \
        [ "${1%.xsd}" = "STD" ]
    then
        return 1
    fi

    return 0
}

# Check if the a schema is the most recent version (return true) or legacy (return false)
# $1=schema name
# $2=release to check if current
schemastatus() {
    if iscurrent "$1"; then
        if ismostrecent "$1" "$2"; then
            echo "currently in use (and is the most recent release)"
        else
            echo "currently in use (but superseded by a more recent release)"
        fi
    else
        if ismostrecent "$1" "$2"; then
            echo "no longer in use (final release)"
        else
            echo "no longer in use (and superseded by a more recent release)"
        fi
    fi
}

# Get the version of a schema
# $1=schema name
# $2=release to check if current
schemaversion() {
        version=$(grep "version=" "released-schema/$2/$1" | grep -v 'xml' | head -n1 | sed -e 's;^.*version="\([0-9][0-9]*\)".*$;\1;')
        if [ -z "$version" ]; then
            version="1"
        fi
        echo "$version"
}

# Describe a schema (single sentence)
schemadesc() {
    case "${1%.xsd}" in
        BinaryFile)
            echo "Binary File schema used to describe a file location, or the location of a fragment within a file." ;;
        OME|ome)
            echo "main schema which defines the OME ontology for microscopy. This schema makes use of the others." ;;

        OMERO)
            echo "schema extensions used by OMERO. It is not used by the OME schema but provides a structure for data in StructuredAnnotation blocks used by OMERO." ;;
        ROI)
            echo "Region Of Interest schema." ;;
        SA)
            echo "Structured Annotation schema." ;;
        SPW)
            echo "Screen/Plate/Well schema." ;;
        AnalysisChain)
            echo "Analysis Chain schema. Analysis chains are how module outputs are connected to inputs of other modules." ;;
        AnalysisModule)
            echo "Analysis Module Library schema. Analysis modules are image analysis algorithms or, more generally, how information is generated in OME. Makes use of CLI and MLI schemas." ;;
        CA)
            echo "standard Custom Attribute schema." ;;
        CLI)
            echo "Command Line Interface sub-schema." ;;
        DataHistory)
            echo "Data History schema. Data history describes the data dependency in OME." ;;
        MLI)
            echo "Matlab Interface sub-schema." ;;
        STD)
            echo "Semantic Type definition schema. Once a Semantic Type is defined, data for the defined type can be imported into the OME server." ;;
        *)
            echo "${1%.xsd} schema." ;;
    esac
}

# from http://stackoverflow.com/questions/2829613/how-do-you-tell-if-a-string-contains-another-string-in-unix-shell-scripting
# contains(string, substring)
#
# Returns 0 if the specified string contains the specified substring,
# otherwise returns 1.
contains() {
    string="$1"
    substring="$2"
    if test "${string#*$substring}" != "$string"
    then
        return 0    # $substring is in $string
    else
        return 1    # $substring is not in $string
    fi
}

devmarker="dev"
root=published


# Clean up

rm -rf "$root"
mkdir -p "$root"

for dir in released-schema/20*
do
    # Don't copy legacy or other material
    if [ "$dir" = "released-schema/additions" ]; then
        continue
    fi

    # Copy dev material, but don't make index
    if contains $dir $devmarker; then
        echo "DEV Folder Found"
        for schema in "$dir"/*.xsd
        do
            rel=$(basename "$dir")
            base=${schema%.xsd}
            base=$(basename "$base")
            name=$(basename "$schema")

            # For some reason, the OME schema has always been lowercased
            if [ "$base" = "ome" ]; then
                base="OME"
            fi

            path="${root}/Schemas/${base}/${rel}"

            # Copy schema
            mkdir -p "$path"
            cp -v "$schema" "${path}/${name}"

        done
        continue
    fi

    for schema in "$dir"/*.xsd
    do
        rel=$(basename "$dir")
        base=${schema%.xsd}
        base=$(basename "$base")
        name=$(basename "$schema")
        type="$(schemastatus "$name" "$rel")"
        version="$(schemaversion "$name" "$rel")"

        year=$(echo "$rel" | sed -e 's;^\([0-9][0-9]*\)-.*$;\1;')
        month=$(echo "$rel" | sed -e 's;^.*-\([0-9][0-9]*\)$;\1;')

        # Skip files only used internally for legacy schema
        if [ "$rel" = "2003-FC" ] && [ "$base" != "ome" ]; then
            continue;
        fi

        # For some reason, the OME schema has always been lowercased
        if [ "$base" = "ome" ]; then
            base="OME"
        fi

        if [ -z "$version" ]; then
            version=1
        fi

        # Special case copying of legacy schemas
        if [ "$year" = "2003" ]; then
            path="${root}/XMLschemas/${base}/${month}"
            path=$(echo "$path" | sed -e 's;/2003-\(.*\);/\1;')
            reldate="2003 ($month)"
        else
            path="${root}/Schemas/${base}/${rel}"
            reldate=$(parsedate "$rel")
        fi

        # Copy schema
        mkdir -p "$path"
        cp -v "$schema" "${path}/${name}"

        # Generate companion HTML index.html
        echo "HTML [1] -> ${path}/index.html"
        cat <<EOF > "${path}/index.html"
<?xml version='1.0'?>
<!DOCTYPE html PUBLIC "-//XML-DEV//DTD XHTML RDDL 1.0//EN" "http://www.w3.org/2001/rddl/rddl-xhtml.dtd" >
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:rddl="http://www.rddl.org/" xml:lang="en">
<head>
        <title>Open Microscopy Environment ${base} Schema</title>
</head>
<body>
<h1>Open Microscopy Environment OME Schema</h1>
<div class="head">
<p>${reldate}</p>
</div>
<div id="toc">
<h2>Table of contents</h2>
        <ol>
                <li><a href="#intro">Introduction</a></li>
                <li><a href="#status">Status</a></li>
                <li><a href="#schema">Schema</a></li>
        </ol>
</div>
<div id="intro">
<h2>Introduction</h2>
<p>This document outlines the ${base} Schema created by the Open Microscopy Environment Group. Detailed information on the schema and future development plans are available at <a href="http://www.openmicroscopy.org/site/support/file-formats">http://www.openmicroscopy.org/site/support/file-formats</a>. Further information on the groups work is available at <a href="http://www.openmicroscopy.org/">http://www.openmicroscopy.org/</a>
</p>
</div>
<div id="status">
<h2>Status</h2>
<p>This schema is <strong>${type}</strong> and at version <strong>${version}</strong>.</p>
<p>A list of the current versions of all the Open Microscopy Environment Group schemas is available at <a href="http://www.openmicroscopy.org/Schemas/">http://www.openmicroscopy.org/Schemas/</a></p>
</div>
<div id="schema">
<h2>Schema</h2>
<p>The schema XSD file is <a href="${name}">${name}</a>.</p>
<p>Note: Some browsers will try to render XSD files when you view them. This can result in either a blank screen or unformatted text. Choose to either download the file or view the source.</p>
</div>
<hr/>
</body>
</html>
EOF
    done
done

# Special cases

# Transforms folder
path="${root}/Schemas/Transforms/"
dir="transforms"
mkdir -p "$path"
for transform in "$dir"/*.xsl
do
    cp -v "$transform" "$path"
done

# Samples folder
path="${root}/Schemas/Samples/"
dir="samples"
mkdir -p "$path"
for sample in "$dir"/*
do
    cp -vRL "$sample" "$path"
done

# Root index

# Create an HTML link for a schema.
# $1=schema
# $2=year (may be blank)
# $3=filter (current or legacy)
# $4=verbose (true or false)
# $5=schema set (current or legacy)
# $6=schema location (current=Schemas, legacy=XMLschemas)
createlink() {
    name=$(basename "$1")
    release="$2"
    shortname="${name%.xsd}"
    if [ "$shortname" = "ome" ]; then
        shortname="OME"
    fi
    if [ "$5" = "legacy" ]; then
        reldate="2003 ($2)"
    else
        if [ -z "$2" ]; then
            release=$(mostrecentversion "$name")
            reldate=$(parsedate "$release")
        else
            reldate=$(parsedate "$2")
        fi
    fi
    if [ "$5" = "current" ]; then
        relversion=$(schemaversion "$name" "$release")
    else
        relversion=$(schemaversion "$name" "2003-$release")
    fi
    reldesc=" The $(schemadesc "$name")"
    if [ "$4" = "false" ]; then
        reldesc=""
    fi
    if [ "$5" = "current" ]; then
        link=$(find published/Schemas -name "$name" | grep "$release" | head -n1)
        link=$(echo "$link" | sed -e 's;published/Schemas/;;')
        if [ "$6" = "legacy" ]; then
            if [ -z "$2" ]; then
                link="../Schemas/$link"
            else
                link="../../Schemas/$link"
            fi
        fi
    else
        link=$(find published/XMLschemas -name "$name" | grep "$release" | head -n1)
        link=$(echo "$link" | sed -e 's;published/XMLschemas/;;')
        if [ "$6" = "current" ]; then
            if [ -z "$2" ]; then
                link="../XMLschemas/$link"
            else
                link="../../XMLschemas/$link"
            fi
        fi
    fi
    if [ -n "$2" ]; then
        link=$(echo "$link" | sed -e "s;^${shortname}/;;")
    fi
    if [ -z "$2" ]; then
        line="<li>${name} - $reldate, version ${relversion} [<a href=\"${link}\">${name}</a>]${reldesc}</li>"
    else
        line="<li>${name} - $reldate, version ${relversion} [<a href=\"${link}\">${2}</a>]${reldesc}</li>"
    fi
    if [ -z "$2" ]; then
        if iscurrent "$name" && [ "$3" = "current" ]; then
            echo "$line"
        elif ! iscurrent "$name" && [ "$3" != "current" ]; then
            echo "$line"
        fi
    else
        if ismostrecent "$name" "$2" && [ "$3" = "current" ]; then
            echo "$line"
        elif ! ismostrecent "$name" "$2" && [ "$3" != "current" ]; then
            echo "$line"
        fi
    fi
}

# Create main HTML index page

createmainindex() {
    cat <<EOF
<?xml version='1.0'?>
<!DOCTYPE html PUBLIC "-//XML-DEV//DTD XHTML RDDL 1.0//EN" "http://www.w3.org/2001/rddl/rddl-xhtml.dtd" >
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:rddl="http://www.rddl.org/" xml:lang="en">
<head>
        <title>Open Microscopy Environment Schemas</title>
</head>
<body>
<h1>Open Microscopy Environment Schemas</h1>
<div class="head">
<p>$(curdate)</p>
</div>
<div id="toc">
<h2>Table of contents</h2>
        <ol>
                <li><a href="#intro">Introduction</a></li>
                <li><a href="#history">History</a></li>
                <li><a href="#schema.list">Schemas</a></li>
        </ol>
</div>
<div id="intro">
<h2>Introduction</h2>
<p>This document outlines the XML Schemas created by the Open Microscopy Environment Group. Detailed information on the schemas and future development plans are available at <a href="http://www.openmicroscopy.org/site/support/file-formats">http://www.openmicroscopy.org/site/support/file-formats</a>. Further information on the groups work is available at <a href="http://www.openmicroscopy.org/">http://www.openmicroscopy.org/</a>
</p>
<p>Auto generated documentation for the schemas is available on the development server: <a href="http://www.openmicroscopy.org/Schemas/Documentation/Generated/OME-2015-01/ome.html">http://www.openmicroscopy.org/Schemas/Documentation/Generated/OME-2015-01/ome.html</a> and <a  href="http://www.openmicroscopy.org/Schemas/Documentation/Generated/OME-2011-06/OMERO.html">http://www.openmicroscopy.org/Schemas/Documentation/Generated/OME-2011-06/OMERO.html</a>
</p>
</div>
EOF

    cat <<EOF
<div id="history">
<h2>History</h2>
<p>This lists the most recent version of past schemas. The schemas are in a process of constant development to extend and refine the OME Data Model.
</p>
<ul>
EOF

    for release in $(ls -1d released-schema/20* | grep -v 2003 | grep -v $devmarker | xargs $XARGSOPTS -n1 basename | sort -r); do
        reldate=$(parsedate "$release")
        echo "<li>$reldate - namespace /$release/</li>"
    done
    for release in $(ls -1d released-schema/20* | grep 2003 | xargs $XARGSOPTS -n1 basename | sort -r | grep FC | sed -e 's;2003-\(.*\);\1;') $(ls -1d released-schema/20* | grep 2003 | xargs $XARGSOPTS -n1 basename | sort -r | grep -v FC | sed -e 's;2003-\(.*\);\1;'); do
        reldate="2003 ($release)"
        echo "<li>$reldate - namespace /$release/*.xsd</li>"
    done

    cat <<EOF
</ul>
<p>Information regarding schemas released before June 2007 is available at <a href="http://www.openmicroscopy.org/XMLschemas/">http://www.openmicroscopy.org/XMLschemas/</a>. This includes the schemas used by the original OME server.
</p>
</div>
<div id="schema.list">
<h2>Schemas</h2>
<p>This has the schema name, the current version, a link to the XSD file, and a short description</p>
<p><em>Note: Some browsers will try to render XSD files when you view them. This can result in either a blank screen or unformatted text. Choose to either download the file or view the source.</em></p>
<h4>Active Schemas</h4>
<ul>
EOF

    for schema in $(find published/Schemas -name '*xsd' | grep -v "Samples" | xargs $XARGSOPTS -n1 basename | sort | uniq ); do
        createlink "$schema" "" "current" "true" "current" "$1"
    done

    cat <<EOF
</ul>
<h4>Legacy Schemas</h4>
<ul>
EOF

    for schema in $(find published/Schemas -name '*xsd' | grep -v "Samples" | xargs $XARGSOPTS -n1 basename | sort | uniq); do
        createlink "$schema" "" "legacy" "true" "current" "$1"
    done
    cat <<EOF
</ul>
</div>
<hr/>
</body>
</html>
EOF
}

createintermediateindex() {
    current="This schema is currently used."
    if ! iscurrent "$1"; then
        current="This schema is no longer in use."
    fi
    schema="$1.xsd"
    if [ "$1" = "OME" ]; then
        schema="ome.xsd"
    fi

    cat <<EOF
<?xml version='1.0'?>
<!DOCTYPE html PUBLIC "-//XML-DEV//DTD XHTML RDDL 1.0//EN" "http://www.w3.org/2001/rddl/rddl-xhtml.dtd" >
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:rddl="http://www.rddl.org/" xml:lang="en">
<head>
        <title>Open Microscopy Environment $1 Schemas</title>
</head>
<body>
<h1>Open Microscopy Environment $1 Schemas</h1>
<div class="head">
<p>$(curdate)</p>
</div>
<div id="toc">
<h2>Table of contents</h2>
        <ol>
                <li><a href="#intro">Introduction</a></li>
                <li><a href="#history">History</a></li>
                <li><a href="#schema.list">Schemas</a></li>
        </ol>
</div>
<div id="intro">
<h2>Introduction</h2>
<p>This document outlines the XML $1 Schemas created by the Open Microscopy Environment Group. This is the $(schemadesc "$1")  Detailed information on the schemas and future development plans are available at <a href="http://www.openmicroscopy.org/site/support/file-formats">http://www.openmicroscopy.org/site/support/file-formats</a>. Further information on the groups work is available at <a href="http://www.openmicroscopy.org/">http://www.openmicroscopy.org/</a>
</p>
</div>
EOF

    cat <<EOF
<div id="history">
<h2>History</h2>
<p>This lists the current and prior versions of the $1 schema. The schemas are in a process of constant development to extend and refine the OME Data Model.
</p>
<ul>
EOF

    for release in $(ls -1d "$root"/Schemas/$1/20* | xargs $XARGSOPTS -n1 basename | grep -v $devmarker | grep -v html | sort -r); do
        reldate=$(parsedate "$release")
        echo "<li>$reldate - namespace /$release/</li>"
    done
    if [ -d "${root}/XMLschemas/$1" ]; then
        for release in $(ls -1d "$root"/XMLschemas/$1/* | xargs $XARGSOPTS -n1 basename | grep -v $devmarker | grep -v html  | sort -r | grep FC) $(ls -1d "$root"/XMLschemas/$1/* | xargs $XARGSOPTS -n1 basename | grep -v $devmarker | grep -v html | sort -r | grep -v FC); do
            reldate="2003 ($release)"
            echo "<li>$reldate - namespace /$release/$schema</li>"
        done
    fi


    cat <<EOF
</ul>
<p>Information regarding schemas released before June 2007 is available at <a href="http://www.openmicroscopy.org/XMLschemas/">http://www.openmicroscopy.org/XMLschemas/</a>. This includes the schemas used by the original OME server.
</p>
</div>
<div id="schema.list">
<h2>Schemas</h2>
<p>This has the schema name, the current version, a link to the XSD file, and a short description</p>
<p><em>Note: Some browsers will try to render XSD files when you view them. This can result in either a blank screen or unformatted text. Choose to either download the file or view the source.</em></p>
<p><b>$current</b></p>
<h4>Most recent schema</h4>
<ul>
EOF

    for year in $(find published/Schemas -name "$schema" | grep -v "Samples" | xargs $XARGSOPTS -n1 dirname | xargs $XARGSOPTS -n1 basename | grep -v $devmarker | grep -v html | sort -r); do
        createlink "$schema" "$year" "current" "false" "current" "$2"
    done
    for year in $(find published/XMLschemas -name "$schema" | grep -v "Samples" | xargs $XARGSOPTS -n1 dirname | xargs $XARGSOPTS -n1 basename | grep -v $devmarker | grep -v html | sort -r | grep FC) $(find published/XMLschemas -name "$schema" | grep -v "Samples" | xargs $XARGSOPTS -n1 dirname | xargs $XARGSOPTS -n1 basename | grep -v $devmarker | grep -v html | sort -r | grep -v FC); do
        createlink "$schema" "$year" "current" "false" "legacy" "$2"
    done

    cat <<EOF
</ul>
<h4>Older schemas</h4>
<ul>
EOF

    for year in $(find published/Schemas -name "$schema" | grep -v "Samples" | xargs $XARGSOPTS -n1 dirname | xargs $XARGSOPTS -n1 basename | grep -v $devmarker | grep -v html | sort -r); do
        createlink "$schema" "$year" "legacy" "false" "current" "$2"
    done
    for year in $(find published/XMLschemas -name "$schema" | grep -v "Samples" | xargs $XARGSOPTS -n1 dirname | xargs $XARGSOPTS -n1 basename | grep -v $devmarker | grep -v html | sort -r | grep FC) $(find published/XMLschemas -name "$schema" | grep -v "Samples" | xargs $XARGSOPTS -n1 dirname | xargs $XARGSOPTS -n1 basename | grep -v $devmarker | grep -v html | sort -r | grep -v FC); do
        createlink "$schema" "$year" "legacy" "false" "legacy" "$2"
    done

    cat <<EOF
</ul>
</div>
<hr/>
</body>
</html>
EOF
}

for type in $(find "${root}/Schemas" -mindepth 1 -maxdepth 1 -type d | sed -e 's;^published/Schemas/;;'); do
    if [ $type != "Samples" ] && [ $type != "Transforms" ]; then
        echo "HTML [2] -> $root/Schemas/${type}/index.html"
        createintermediateindex "$type" "current" > "$root/Schemas/${type}/index.html"
    fi
done

for type in $(find "${root}/XMLschemas" -mindepth 1 -maxdepth 1 -type d | sed -e 's;^published/XMLschemas/;;'); do
    if [ $type != "Samples" ] && [ $type != "Transforms" ]; then
        echo "HTML [3] -> $root/XMLschemas/${type}/index.html"
        createintermediateindex "$type" "legacy" > "$root/XMLschemas/${type}/index.html"
    fi
done

echo "HTML [4] -> ${root}/Schemas/index.html"
createmainindex "current" > "${root}/Schemas/index.html"
echo "HTML [5] -> ${root}/XMLschemas/index.html"
createmainindex "legacy" > "${root}/XMLschemas/index.html"

echo "Add any web-extras"
if [ -d "web-extra" ]; then
    rsync --stats -r -t "web-extra/" "${root}"
fi

